home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo2.zoo / demo / ex / ex_cmds2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-24  |  8.9 KB  |  562 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char *sccsid = "@(#)ex_cmds2.c    7.5 (Berkeley) 3/9/87; 1.2 (Bellcore)    87/04/24";
  9. #endif not lint
  10.  
  11. #include "ex.h"
  12. #include "ex_argv.h"
  13. #include "ex_temp.h"
  14. #include "ex_tty.h"
  15. #include "ex_vis.h"
  16.  
  17. extern bool    pflag, nflag;        /* mjm: extern; also in ex_cmds.c */
  18. extern int    poffset;        /* mjm: extern; also in ex_cmds.c */
  19.  
  20. /*
  21.  * Subroutines for major command loop.
  22.  */
  23.  
  24. /*
  25.  * Is there a single letter indicating a named buffer next?
  26.  */
  27. cmdreg()
  28. {
  29.     register int c = 0;
  30.     register int wh = skipwh();
  31.  
  32.     if (wh && isalpha(peekchar()))
  33.         c = ex_getchar();
  34.     return (c);
  35. }
  36.  
  37. /*
  38.  * Tell whether the character ends a command
  39.  */
  40. endcmd(ch)
  41.     int ch;
  42. {
  43.     switch (ch) {
  44.     
  45.     case '\n':
  46.     case EOF:
  47.         endline = 1;
  48.         return (1);
  49.     
  50.     case '|':
  51.     case '"':
  52.         endline = 0;
  53.         return (1);
  54.     }
  55.     return (0);
  56. }
  57.  
  58. /*
  59.  * Insist on the end of the command.
  60.  */
  61. eol()
  62. {
  63.  
  64.     if (!skipend())
  65.         error("Extra chars|Extra characters at end of command");
  66.     ignnEOF();
  67. }
  68.  
  69. /*
  70.  * Print out the message in the error message file at str,
  71.  * with i an integer argument to printf.
  72.  */
  73. /*VARARGS2*/
  74. error(str, i)
  75. #ifndef EXSTRINGS
  76.     char *str;
  77. #else
  78. # ifdef lint
  79.     char *str;
  80. # else
  81.     int str;
  82. # endif
  83. #endif
  84.     int i;
  85. {
  86.  
  87.     error0();
  88.     merror(str, i);
  89.     if (writing) {
  90.         serror(" [Warning - %s is incomplete]", file);
  91.         writing = 0;
  92.     }
  93.     error1(str);
  94. }
  95.  
  96. /*
  97.  * Rewind the argument list.
  98.  */
  99. erewind()
  100. {
  101.  
  102.     argc = argc0;
  103.     argv = argv0;
  104.     args = args0;
  105.     if (argc > 1 && !hush) {
  106.         ex_printf(mesg("%d files@to edit"), argc);
  107.         if (inopen)
  108.             ex_putchar(' ');
  109.         else
  110.             putNFL();
  111.     }
  112. }
  113.  
  114. /*
  115.  * Guts of the pre-printing error processing.
  116.  * If in visual and catching errors, then we dont mung up the internals,
  117.  * just fixing up the echo area for the print.
  118.  * Otherwise we reset a number of externals, and discard unused input.
  119.  */
  120. error0()
  121. {
  122.  
  123.     if (vcatch) {
  124.         if (splitw == 0)
  125.             fixech();
  126.         if (!SO || !SE)
  127.             dingdong();
  128.         return;
  129.     }
  130.     if (input) {
  131.         input = strend(input) - 1;
  132.         if (*input == '\n')
  133.             setlastchar('\n');
  134.         input = 0;
  135.     }
  136.     setoutt();
  137.     flush();
  138.     resetflav();
  139.     if (!SO || !SE)
  140.         dingdong();
  141.     if (inopen) {
  142.         /*
  143.          * We are coming out of open/visual ungracefully.
  144.          * Restore COLUMNS, undo, and fix tty mode.
  145.          */
  146.         COLUMNS = OCOLUMNS;
  147.         undvis();
  148.         ostop(normf);
  149.         /* ostop should be doing this
  150.         putpad(VE);
  151.         putpad(KE);
  152.         */
  153.         putnl();
  154.     }
  155.     inopen = 0;
  156.     holdcm = 0;
  157. }
  158.  
  159. /*
  160.  * Post error printing processing.
  161.  * Close the i/o file if left open.
  162.  * If catching in visual then throw to the visual catch,
  163.  * else if a child after a fork, then exit.
  164.  * Otherwise, in the normal command mode error case,
  165.  * finish state reset, and throw to top.
  166.  */
  167. error1(str)
  168.     char *str;
  169. {
  170.     bool die;
  171.  
  172.     if (io > 0) {
  173.         close(io);
  174.         io = -1;
  175.     }
  176.     die = (getpid() != ppid);    /* Only children die */
  177.     inappend = inglobal = 0;
  178.     globp = vglobp = vmacp = 0;
  179.     if (vcatch && !die) {
  180.         inopen = 1;
  181.         vcatch = 0;
  182.         if (str)
  183.             noonl();
  184.         fixol();
  185.         longjmp(vreslab,1);
  186.     }
  187.     if (str && !vcatch)
  188.         putNFL();
  189.     if (die)
  190.         ex_exit(1);
  191.     lseek(0, 0L, 2);
  192.     if (inglobal)
  193.         setlastchar('\n');
  194.     while (lastchar() != '\n' && lastchar() != EOF)
  195.         ignchar();
  196.     ungetchar(0);
  197.     endline = 1;
  198.     reset();
  199. }
  200.  
  201. fixol()
  202. {
  203.     if (Outchar != vputchar) {
  204.         flush();
  205.         if (state == ONEOPEN || state == HARDOPEN)
  206.             outline = destline = 0;
  207.         Outchar = vputchar;
  208.         vcontin(1);
  209.     } else {
  210.         if (destcol)
  211.             vclreol();
  212.         vclean();
  213.     }
  214. }
  215.  
  216. /*
  217.  * Does an ! character follow in the command stream?
  218.  */
  219. exclam()
  220. {
  221.  
  222.     if (peekchar() == '!') {
  223.         ignchar();
  224.         return (1);
  225.     }
  226.     return (0);
  227. }
  228.  
  229. /*
  230.  * Make an argument list for e.g. next.
  231.  */
  232. makargs()
  233. {
  234.  
  235.     glob(&frob);
  236.     argc0 = frob.argc0;
  237.     argv0 = frob.argv;
  238.     args0 = argv0[0];
  239.     erewind();
  240. }
  241.  
  242. /*
  243.  * Advance to next file in argument list.
  244.  */
  245. next()
  246. {
  247.     extern short isalt;    /* defined in ex_io.c */
  248.  
  249.     if (argc == 0)
  250.         error("No more files@to edit");
  251.     morargc = argc;
  252.     isalt = (strcmp(altfile, args)==0) + 1;
  253.     if (savedfile[0])
  254.         CP(altfile, savedfile);
  255.     CP(savedfile, args);
  256.     argc--;
  257.     args = argv ? *++argv : strend(args) + 1;
  258. }
  259.  
  260. /*
  261.  * Eat trailing flags and offsets after a command,
  262.  * saving for possible later post-command prints.
  263.  */
  264. newline()
  265. {
  266.     register int c;
  267.  
  268.     resetflav();
  269.     for (;;) {
  270.         c = ex_getchar();
  271.         switch (c) {
  272.  
  273.         case '^':
  274.         case '-':
  275.             poffset--;
  276.             break;
  277.  
  278.         case '+':
  279.             poffset++;
  280.             break;
  281.  
  282.         case 'l':
  283.             listf++;
  284.             break;
  285.  
  286.         case '#':
  287.             nflag++;
  288.             break;
  289.  
  290.         case 'p':
  291.             listf = 0;
  292.             break;
  293.  
  294.         case ' ':
  295.         case '\t':
  296.             continue;
  297.  
  298.         case '"':
  299.             comment();
  300.             setflav();
  301.             return;
  302.  
  303.         default:
  304.             if (!endcmd(c))
  305. serror("Extra chars|Extra characters at end of \"%s\" command", Command);
  306.             if (c == EOF)
  307.                 ungetchar(c);
  308.             setflav();
  309.             return;
  310.         }
  311.         pflag++;
  312.     }
  313. }
  314.  
  315. /*
  316.  * Before quit or respec of arg list, check that there are
  317.  * no more files in the arg list.
  318.  */
  319. nomore()
  320. {
  321.  
  322.     if (argc == 0 || morargc == argc)
  323.         return;
  324.     morargc = argc;
  325.     merror("%d more file", argc);
  326.     serror("%s@to edit", plural((long) argc));
  327. }
  328.  
  329. /*
  330.  * Before edit of new file check that either an ! follows
  331.  * or the file has not been changed.
  332.  */
  333. quickly()
  334. {
  335.  
  336.     if (exclam())
  337.         return (1);
  338.     if (chng && dol > zero) {
  339. /*
  340.         chng = 0;
  341. */
  342.         xchng = 0;
  343.         serror("No write@since last change (:%s! overrides)", Command);
  344.     }
  345.     return (0);
  346. }
  347.  
  348. /*
  349.  * Reset the flavor of the output to print mode with no numbering.
  350.  */
  351. resetflav()
  352. {
  353.  
  354.     if (inopen)
  355.         return;
  356.     listf = 0;
  357.     nflag = 0;
  358.     pflag = 0;
  359.     poffset = 0;
  360.     setflav();
  361. }
  362.  
  363. /*
  364.  * Print an error message with a %s type argument to printf.
  365.  * Message text comes from error message file.
  366.  */
  367. serror(str, cp)
  368. #ifdef lint
  369.     register char *str;
  370. #else
  371.     register int str;
  372. #endif
  373.     char *cp;
  374. {
  375.  
  376.     error0();
  377.     smerror(str, cp);
  378.     error1(str);
  379. }
  380.  
  381. /*
  382.  * Set the flavor of the output based on the flags given
  383.  * and the number and list options to either number or not number lines
  384.  * and either use normally decoded (ARPAnet standard) characters or list mode,
  385.  * where end of lines are marked and tabs print as ^I.
  386.  */
  387. setflav()
  388. {
  389.  
  390.     if (inopen)
  391.         return;
  392.     ignorf(setnumb(nflag || value(NUMBER)));
  393.     ignorf(setlist(listf || value(LIST)));
  394.     setoutt();
  395. }
  396.  
  397. /*
  398.  * Skip white space and tell whether command ends then.
  399.  */
  400. skipend()
  401. {
  402.  
  403.     pastwh();
  404.     return (endcmd(peekchar()) && peekchar() != '"');
  405. }
  406.  
  407. /*
  408.  * Set the command name for non-word commands.
  409.  */
  410. tailspec(c)
  411.     int c;
  412. {
  413.     static char foocmd[2];
  414.  
  415.     foocmd[0] = c;
  416.     Command = foocmd;
  417. }
  418.  
  419. /*
  420.  * Try to read off the rest of the command word.
  421.  * If alphabetics follow, then this is not the command we seek.
  422.  */
  423. tail(comm)
  424.     char *comm;
  425. {
  426.  
  427.     tailprim(comm, 1, 0);
  428. }
  429.  
  430. tail2of(comm)
  431.     char *comm;
  432. {
  433.  
  434.     tailprim(comm, 2, 0);
  435. }
  436.  
  437. char    tcommand[20];
  438.  
  439. tailprim(comm, i, notinvis)
  440.     register char *comm;
  441.     int i;
  442.     bool notinvis;
  443. {
  444.     register char *cp;
  445.     register int c;
  446.  
  447.     Command = comm;
  448.     for (cp = tcommand; i > 0; i--)
  449.         *cp++ = *comm++;
  450.     while (*comm && peekchar() == *comm)
  451.         *cp++ = ex_getchar(), comm++;
  452.     c = peekchar();
  453.     if (notinvis || isalpha(c)) {
  454.         /*
  455.          * Of the trailing lp funny business, only dl and dp
  456.          * survive the move from ed to ex.
  457.          */
  458.         if (tcommand[0] == 'd' && any(c, "lp"))
  459.             goto ret;
  460.         if (tcommand[0] == 's' && any(c, "gcr"))
  461.             goto ret;
  462.         while (cp < &tcommand[19] && isalpha(peekchar()))
  463.             *cp++ = ex_getchar();
  464.         *cp = 0;
  465.         if (notinvis)
  466.             serror("What?|%s: No such command from open/visual", tcommand);
  467.         else
  468.             serror("What?|%s: Not an editor command", tcommand);
  469.     }
  470. ret:
  471.     *cp = 0;
  472. }
  473.  
  474. /*
  475.  * Continue after a : command from open/visual.
  476.  */
  477. vcontin(ask)
  478.     bool ask;
  479. {
  480.  
  481.     if (vcnt > 0)
  482.         vcnt = -vcnt;
  483.     if (inopen) {
  484.         if (state != VISUAL) {
  485.             /*
  486.              * We don't know what a shell command may have left on
  487.              * the screen, so we move the cursor to the right place
  488.              * and then put out a newline.  But this makes an extra
  489.              * blank line most of the time so we only do it for :sh
  490.              * since the prompt gets left on the screen.
  491.              *
  492.              * BUG: :!echo longer than current line \\c
  493.              * will screw it up, but be reasonable!
  494.              */
  495.             if (state == CRTOPEN) {
  496.                 termreset();
  497.                 vgoto(WECHO, 0);
  498.             }
  499.             if (!ask) {
  500.                 putch('\r');
  501.                 putch('\n');
  502.             }
  503.             return;
  504.         }
  505.         if (ask) {
  506.             merror("[Hit return to continue] ");
  507.             flush();
  508.         }
  509. #ifndef CBREAK
  510.         vraw();
  511. #endif
  512.         if (ask) {
  513. #ifdef EATQS
  514.             /*
  515.              * Gobble ^Q/^S since the tty driver should be eating
  516.              * them (as far as the user can see)
  517.              */
  518.             while (peekkey() == CTRL(Q) || peekkey() == CTRL(S))
  519.                 ignore(getkey());
  520. #endif
  521.             if(getkey() == ':') {
  522.                 /* Ugh. Extra newlines, but no other way */
  523.                 putch('\n');
  524.                 outline = WECHO;
  525.                 ungetkey(':');
  526.             }
  527.         }
  528.         vclrech(1);
  529.         if (Peek_key != ':') {
  530.             putpad(TI);
  531.             tostart();
  532.             /* replaced by ostart.
  533.             putpad(VS);
  534.             putpad(KS);
  535.             */
  536.         }
  537.     }
  538. }
  539.  
  540. /*
  541.  * Put out a newline (before a shell escape)
  542.  * if in open/visual.
  543.  */
  544. vnfl()
  545. {
  546.  
  547.     if (inopen) {
  548.         if (state != VISUAL && state != CRTOPEN && destline <= WECHO)
  549.             vclean();
  550.         else
  551.             vmoveitup(1, 0);
  552.         vgoto(WECHO, 0);
  553.         vclrbyte(vtube[WECHO], WCOLS);
  554.         tostop();
  555.         /* replaced by the ostop above
  556.         putpad(VE);
  557.         putpad(KE);
  558.         */
  559.     }
  560.     flush();
  561. }
  562.